/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.store.client.components;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.elf.gwt.common.client.access.RequestParameter;
import com.elf.gwt.common.client.callback.TableNavigatorWidgetCallback;
import com.elf.gwt.common.client.components.CommonSimpleComponent;
import com.elf.gwt.common.client.exception.NoResultsFoundException;
import com.elf.gwt.common.client.model.OrderModel;
import com.elf.gwt.common.client.model.OrderSummaryModel;
import com.elf.gwt.common.client.model.OrderbyModel;
import com.elf.gwt.common.client.model.OrdersSummaryMetaModel;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.elf.gwt.common.client.widget.TableNavigatorWidget;
import com.elf.gwt.store.client.GWTCommerceConstants;
import com.elf.gwt.store.client.StoreComponentController;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;

/**
 *  
 */
public class OrdersSummaryComponent extends JSONServerComponent
{	
	protected OrdersSummaryMetaModel ordersSummaryMetaModel;
	protected List<OrderSummaryModel> orderSummaryModels;
	protected TableNavigatorWidgetCallback navCallback;
	protected TableNavigatorWidget navPanelTop;
	protected TableNavigatorWidget navPanelBot;
	protected OrderSummaryModel ordersSummaryModel;
	protected OrderModel orderModel;
	protected List<OrderbyModel> orderbyModels;

	/**
	 * Constructor
	 */
	public OrdersSummaryComponent(StoreComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix, null, false);
		ordersSummaryModel = new OrderSummaryModel();
		orderModel = new OrderModel();
		orderSummaryModels = new ArrayList<OrderSummaryModel>();
		this.setLoginRequired(true);
	}

	public boolean updateFromHistoryParameters(String[] params)
	{
		if (!super.updateFromHistoryParameters(params)) return false;
				
		int offset = ordersSummaryModel.getOffset();
		String orderby = ordersSummaryModel.getOrderby();
		try {
			offset = Integer.parseInt(params[1]);
			orderby = params[2];
		}
		catch (Exception e) {}
		if (orderby.equals("*")) orderby = "o.orders_id desc";
		ordersSummaryModel.setOffset(offset);
		ordersSummaryModel.setOrderby(orderby);
		storeController.getMultipleResultsComponent().addComponent(this);

		//Don't look for new products
		CommonSimpleComponent alwaysAskComponent = controller.getComponent("NewProductsComponent", false);
		if (alwaysAskComponent != null) storeController.getMultipleResultsComponent().removeComponent(alwaysAskComponent);

		return true;
	}

	public void additionalRequestParameters()
	{
		addRequestParameter(new RequestParameter("os_offset", ordersSummaryModel.getOffset()));
		addRequestParameter(new RequestParameter("os_orderby", ordersSummaryModel.getOrderby()));
	}

	public void build(Throwable exception)
	{
		GWT.log(getHandle() + ".build()", exception);
		try {
			throw exception;
		}
		catch (NoResultsFoundException ex)
		{
			try {
				orderSummaryModels.clear();
				ordersSummaryMetaModel = new OrdersSummaryMetaModel();
				buildFromModel();
			}
			catch (Exception ex1)
			{
				GWT.log(getHandle() + ".buildFromModel()", ex1);
				panel.setText(1, 0, ex1.toString());
			}
		}
		catch (Throwable ex) {
			panel.setText(1, 0, exception.toString());
		}
		onBuilt();
	}

	protected void buildMetaModel(JSONObject jsonObject) throws Exception
	{
		ordersSummaryMetaModel = new OrdersSummaryMetaModel(jsonObject);
	}

	protected void buildModel(JSONArray jsonArray) throws Exception
	{
		orderSummaryModels.clear();
		super.buildModel(jsonArray);
	}

	protected void buildModel(JSONObject jsonObject) throws Exception
	{
		OrderSummaryModel orderSummaryModel = new OrderSummaryModel(jsonObject);
		orderSummaryModels.add(orderSummaryModel);
	}

	public void buildFromModel() throws Exception
	{
		GWTCommerceConstants constants = storeController.getStoreConstants();
		VerticalPanel bodyPanel = new VerticalPanel();
		panel.setWidget(1, 0, bodyPanel);

		//Order By
		if (orderbyModels == null) {
			orderbyModels = new ArrayList<OrderbyModel>();

			String orderbyDelimiter = " " + constants.AdvancedSearchResultsComponentOrderbyDelimiter() + " ";
			String ascending = orderbyDelimiter + constants.AdvancedSearchResultsComponentOrderbyAscending();
			String descending = orderbyDelimiter + constants.AdvancedSearchResultsComponentOrderbyDescending();

			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentOrderNumber() + ascending, "o.orders_id"));
			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentOrderNumber() + descending, "o.orders_id desc"));
			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentOrderStatus() + ascending, "os.orders_status_name"));
			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentOrderStatus() + descending, "os.orders_status_name desc"));
			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentShippedTo() + ascending, "o.delivery_name"));
			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentShippedTo() + descending, "o.delivery_name desc"));
			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentOrderTotal() + ascending, "ot.value"));
			orderbyModels.add(new OrderbyModel(constants.OrdersSummaryComponentOrderTotal() + descending, "ot.value desc"));
		}

		String orderby = ordersSummaryModel.getOrderby();
		if (orderby != null && orderby.length() > 0)
		{
			Iterator<OrderbyModel> iter = orderbyModels.iterator();
			while (iter.hasNext())
			{
				OrderbyModel orderbyModel = iter.next();
				if (orderby.equals(orderbyModel.getOrderclause()))
				{
					orderbyModel.setSelected(true);
					break;
				}
			}
		}

		//Top Navigation
		if (ordersSummaryMetaModel.getPrevNextBarLocation() == 1 || ordersSummaryMetaModel.getPrevNextBarLocation() == 3)
		{
			if (navPanelTop == null)
			{
				navPanelTop = new TableNavigatorWidget("Orders)", ordersSummaryMetaModel.getTotalRows(), 
						ordersSummaryMetaModel.getMaxRows(), ordersSummaryMetaModel.getRows(), ordersSummaryMetaModel.getOffset(), 
						ordersSummaryMetaModel.getPageLinksMax(), orderbyModels,
						controller.getCommonConstants(), StoreComponentController.languagesComponent.getLanguageModel().getCode(), new ASTableNavigatorCallback(),
						CommonUtils.getImageDirectory());
			}
			else
			{
				navPanelTop.refresh(ordersSummaryMetaModel.getTotalRows(), ordersSummaryMetaModel.getMaxRows(), 
						ordersSummaryMetaModel.getRows(), ordersSummaryMetaModel.getOffset());
			}

			bodyPanel.add(navPanelTop);
			navPanelTop.setStyleName(getHandle() + "NavigationPanel");
		}
		//Table
		int sz = orderSummaryModels.size();

		int colnum = 2;
		Grid bodyTable = new Grid(sz+1, colnum);
		bodyTable.setWidth("100%");
		bodyTable.setStyleName(getHandle() + "BodyTable");
		CellFormatter cf = bodyTable.getCellFormatter();
		bodyPanel.add(bodyTable);

		//Bottom Navigation
		if (ordersSummaryMetaModel.getPrevNextBarLocation() == 2 || ordersSummaryMetaModel.getPrevNextBarLocation() == 3)
		{
			if (navPanelBot == null)
			{
				navPanelBot = new TableNavigatorWidget(constants.OrdersSummaryComponentOrders() + ")", ordersSummaryMetaModel.getTotalRows(), 
						ordersSummaryMetaModel.getMaxRows(), ordersSummaryMetaModel.getRows(), ordersSummaryMetaModel.getOffset(), 
						ordersSummaryMetaModel.getPageLinksMax(), orderbyModels,
						controller.getCommonConstants(), StoreComponentController.languagesComponent.getLanguageModel().getCode(), new ASTableNavigatorCallback(),
						CommonUtils.getImageDirectory());
			}
			else
			{
				navPanelBot.refresh(ordersSummaryMetaModel.getTotalRows(), ordersSummaryMetaModel.getMaxRows(), 
						ordersSummaryMetaModel.getRows(), ordersSummaryMetaModel.getOffset());
			}

			bodyPanel.add(navPanelBot);
			navPanelBot.setStyleName(getHandle() + "NavigationPanel");
		}

		bodyTable.setWidget(0, 0, new InlineLabel(constants.OrdersSummaryComponentOrderSummary()));
		cf.setWidth(0, 0, "1000");
		bodyTable.setWidget(0, 1, new InlineLabel(constants.OrdersSummaryComponentButtons()));
		cf.setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_CENTER);
		cf.setHorizontalAlignment(0, 1, HasHorizontalAlignment.ALIGN_CENTER);
		cf.setStyleName(0, 0, getHandle() + "BodyTableTitle");
		cf.setStyleName(0, 1, getHandle() + "BodyTableTitle");

		NumberFormat fmt = NumberFormat.getCurrencyFormat(StoreComponentController.currenciesComponent.getCurrencyModel().getCode());

		for (int i = 0; i < sz; i++)
		{
			int row = i+1;
			OrderSummaryModel orderSummaryModel = orderSummaryModels.get(i);
			Grid rowGrid = new Grid(3,3);
			rowGrid.setWidth("100%");
			rowGrid.setText(0, 0, constants.OrdersSummaryComponentOrderNumberLabel() + " " + orderSummaryModel.getId());
			rowGrid.setText(1, 0, constants.OrdersSummaryComponentOrderDateLabel() + " " + DateTimeFormat.getFormat(DateTimeFormat.PredefinedFormat.DATE_MEDIUM).format(orderSummaryModel.getDatePurchased()));
			rowGrid.setText(2, 0, constants.OrdersSummaryComponentShipToLabel() + " " + orderSummaryModel.getShipToName());
			rowGrid.setText(0, 1, constants.OrdersSummaryComponentProductsLabel() + " " + orderSummaryModel.getNumberOfProducts());

			double orderTotal = orderSummaryModel.getTotal() * StoreComponentController.currenciesComponent.getCurrencyModel().getValue();

			rowGrid.setText(1, 1, constants.OrdersSummaryComponentOrderTotalLabel() + " " + fmt.format(orderTotal));
			rowGrid.setText(0, 2, constants.OrdersSummaryComponentOrderStatusLabel() + " " + orderSummaryModel.getStatus());

			bodyTable.setWidget(row, 0, rowGrid);
			cf.setWidth(row, 0, "100%");
			cf.setStyleName(row, 0, getHandle() + "BodyTableCell");

			Button detailsButton = new Button(controller.getCommonConstants().Details(), orderClickHandler);
			detailsButton.addStyleName(getHandle() + "BodyTableButton");
			detailsButton.addStyleName("index:" + orderSummaryModel.getId());
			bodyTable.setWidget(row, 1, detailsButton);

			cf.setHorizontalAlignment(row, 0, HasHorizontalAlignment.ALIGN_CENTER);
			cf.setStyleName(row, 1, getHandle() + "BodyTableCell");
		}

		Button cancelButton = new Button(controller.getCommonConstants().GoBack(), 
				new ClickHandler() {
					public void onClick(ClickEvent event) {
						onSelection("AccountComponent--ViewAccount");
					}}
		);
		bodyPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		bodyPanel.add(cancelButton);

		onBuilt();
	}

	public class ASTableNavigatorCallback implements TableNavigatorWidgetCallback
	{
		public void onSelection(int offset)
		{
			ordersSummaryModel.setOffset(offset);
			thisComponent.onSelection(getHistory());
		}

		public void onOrderby(String orderby)
		{
			ordersSummaryModel.setOrderby(orderby);
			thisComponent.onSelection(getHistory());
		}
	}

	public String getHistory()
	{
		String history = "OrdersSummaryComponent--";
		history += ordersSummaryModel.getOffset() + "--";
		history += ordersSummaryModel.getOrderby();

		return history;
	}

	protected ClickHandler orderClickHandler = new ClickHandler() {
		public void onClick(ClickEvent event) {
			Widget source = (Widget)event.getSource();
			String stylenames = source.getStyleName();
			int loc = stylenames.indexOf("index:");
			stylenames = stylenames.substring(loc+6);
			loc = stylenames.indexOf(" ");
			if (loc > -1) stylenames = stylenames.substring(0, loc);
			int order_id = Integer.parseInt(stylenames);
			onSelection("OrderComponent--" + order_id);
		}
	};

	public OrderModel getOrderModel() {
		return orderModel;
	}

	public OrderSummaryModel getOrdersSummaryModel() {
		return ordersSummaryModel;
	}
}
